#include <stdlib.h>
#include "../../xml.h"
#include "../../simple.h"
#include "../../gui_al.h"
#include "../../journal.h"
#include "../../error.h"
#include "../../cryptography.h"
#include "../../gui_io.h"
#include "gui_al.h"
#include "../../second.h"
#include "gui_io.h"
#include "undo.h"
#include "../../settings.h"
#include "../../list.h"


int elog_gui_io_lock_open = 0;

int sync_needed = 0;

int _lock = 0;
int elog_gui_io_lock()
{
	return _lock;
}


void elog_gui_io_setSyncNeeded()
{
	sync_needed = 1;
}


struct dict *elog_gui_getMeta()
{
	struct elog_xml_doc *meta;

	elog_set_currentFile(NULL, &meta);

	if (meta == NULL) {
		meta = elog_xml_doc_new();
		struct elog_xml_doc *tmp = meta;
		elog_set_currentFile(meta->fileName, &tmp);
		//because meta->fileName is null we need something
		//to keep the address from being reassigned!
	}

	if (meta->subject)
		free(meta->subject);
	meta->subject = edit_gui_al_title(NULL);
	if (!(meta->subject)) {
		//setting a subject if none.
		char *txt = edit_gui_al_text(NULL);
		if (txt[0]) {
			meta->subject = malloc((sizeof *(meta->subject)) * 25);
			meta->subject[0] = '\0';
			strncpy(meta->subject, txt, 24);
			meta->subject[24] = '\0';
			edit_gui_al_title(meta->subject);
		}
		free(txt);
	}
	
	meta->weather = edit_gui_al_weather(-1);
	meta->mood = edit_gui_al_mood(-1);

	if (meta->last_edit)
		free(meta->last_edit);
	meta->last_edit = edit_gui_al_lastEdit(NULL);
	if (meta->created)
		free(meta->created);
	meta->created = edit_gui_al_creationDate(NULL);
	//meta->links = elog_gui_al_getLinks(); //we simply keep up with links
	return meta;
}


int edit_gui_io_save()
{

	struct elog_crypt_save *save = malloc(sizeof *save);
	save->enc = elog_journ_current()->settings->encryption;
	save->txt = txt;
	save->len = len;
	save->doc = current;

	elog_xml_doc_ref(current);
	elog_scnd_run_arg(__elog_gui_io_save, "save", save);
	return 0;
}


void elog_gui_io_removeLink(int loc)
{
	struct elog_xml_doc *current;
	elog_set_currentFile(NULL, &current);
	if (current->links == NULL)
		return;
	int c;
	for (c = 0; current->links[c] != NULL; ++c) {
		if (loc <= current->links[c]->start
		    && loc >= current->links[c]->end) {
			char *title =
			    elog_sp_shortToString(current->links[c]->num);

			edit_gui_al_removeLink(title);

			free(title);

			//don't free link, undo needs it!
			int j = c;
			for (; current->links[j] != NULL; ++j)
				current->links[j] = current->links[j + 1];
			break;
		}
	}
}

void edit_gui_previewPane_set(struct dict *meta)
{
	edit_gui_al_mood(-2);
	edit_gui_al_weather(meta->weather);
	edit_gui_al_mood(meta->mood);
	//elog_gui_al_setImage(meta->mood, meta->weather);
	//^^^ gets loaded by the callbacks.
	edit_gui_al_title(meta->subject);

	char *day, *month, *year;
	day = elog_sp_shortToString(meta->day);
	month = (char *) elog_mnth_str(meta->month);

	year = elog_sp_shortToString(meta->year);
	char *str;
	elog_sp_cat(&str, "The ", day, elog_mnth_day(meta->day), " of ",
		    month, ", ", year, NULL);
	edit_gui_al_creationDate(str);
	free(str);
	free(day);
	free(year);
	//dontFree(month);

	edit_gui_al_lastEdit(meta->last_edit);
}

void edit_gui_io_addLink(struct dict *lnk)
{
	struct elog_xml_doc *current;
	elog_set_currentFile(NULL, &current);


	struct elog_xml_link **nue;

	int size = 0;
	if (current->links != NULL)
		for (size = 0; current->links[size] != NULL; ++size);	//size finder

	nue = malloc((sizeof *nue) * (size + 2));
	int c;
	for (c = 0; c < size; ++c)
		nue[c] = current->links[c];
	nue[size] = lnk;
	nue[size + 1] = NULL;
	free(current->links);
	current->links = nue;

	elog_set_currentFile(current->fileName, &current);
	//elog_gui_io_addUndoActionPtr(ELOG_GUI_IO_ACTION_LINK, lnk, 0);
}
int elog_gui_io_checkRange(int loc, struct dict **lnk)
{
	*lnk = NULL;
	struct dict *current;
	elog_set_currentFile(NULL, &current);
	if (!current)
		return 0;
	if (dict_check(current, "links", NULL))
		return 0;
	struct list *links = dict_get(current, "links");
	listiter c = list_start_iter(links);
	for (; c; c = list_iter_next(c)) {
		struct dict *cur = list_iter_get(c);
		if (dict_check(cur, "start", "end", NULL))
			return 0;
		
		if (loc < *((int *)dict_get(cur, "start"))
		    && loc > *((int *)dict_get(cur, "end"))) {
			*lnk = cur;
			return 1;
		}
	}
	return 0;
}
void edit_gui_io_updateTags(int start, int len)
{
	struct dict *current;
	elog_set_currentFile(NULL, &current);
	if (dict_check(current, "links", NULL))
		return;
	struct list *links = dict_get(current, "links");
	listiter c = list_start_iter(links);
	for (; c; c = list_iter_next(c)) {
		struct dict *cur = list_iter_get(c);
		if (dict_check(cur, "start", "end", NULL))
			return;
		if (*((int *)dict_get(cur, "start")) > start) {
			(*((int *)dict_get(cur, "start"))) += len;
			(*((int *)dict_get(cur, "end"))) += len;
		}
	}

}
